﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using EPiServer.Core;
using EPiServer.Filters;
using OpenWaves.EPiServer.Abstractions;
using System.Linq;

namespace OpenWaves.EPiServer
{
    public static class PageDataExtensions
    {
        public static IEnumerable<PageData> GetChildren(this PageData page, bool enableMasterLanguageFallback = false)
        {
            return page.PageLink.GetChildren(LanguageSelector.Fallback(page.LanguageBranch, enableMasterLanguageFallback));
        }

        public static IEnumerable<PageData> GetChildren(this PageData page, IEnumerable<IPageFilter> filters, bool enableMasterLanguageFallback = false)
        {
            Contract.Requires<ArgumentNullException>(filters != null);

            return page.PageLink.GetChildren(filters, LanguageSelector.Fallback(page.LanguageBranch, enableMasterLanguageFallback));
        }

        public static IEnumerable<PageData> GetAncestors(this PageData page, bool enableMasterLanguageFallback = true)
        {
            return page.GetAncestors(PageFilters.PublishedAndAccessible, enableMasterLanguageFallback);
        }

        public static IEnumerable<PageData> GetAncestors(this PageData page, IEnumerable<IPageFilter> filters, bool enableMasterLanguageFallback = true)
        {
            Contract.Requires<ArgumentNullException>(filters != null);
            
            var dataFactory = ServiceLocator.Resolve<IDataFactory>();

            while (page != null && PageReference.IsNullOrEmpty(page.ParentLink) == false)
            {
                page = dataFactory.GetPage(page.ParentLink, LanguageSelector.Fallback(page.LanguageBranch, enableMasterLanguageFallback));

                if (page != null && filters.All(f=>f.ShouldFilter(page) == false))
                    yield return page;
            }
        }   
      
        public static IEnumerable<T> FilteredBy<T>(this IEnumerable<T> pages, IEnumerable<IPageFilter> filters) where T : PageData
        {
            return pages.Where(p => filters.All(f => f.ShouldFilter(p) == false));
        }
    }
}